package com.fast.server.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fast.server.component.RedisComponent;
import com.fast.server.config.sysconfig.AppConfig;
import com.fast.server.config.toemail.RegisterToSendEmails;
import com.fast.server.entity.constants.Constants;
import com.fast.server.entity.vo.SysUser;
import com.fast.server.entity.vo.SysVerificationCode;
import com.fast.server.exception.BusinessException;
import com.fast.server.mapper.SysVerificationCodeMapper;
import com.fast.server.service.ISysUserService;
import com.fast.server.service.ISysVerificationCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.mail.internet.MimeMessage;
import java.time.ZoneOffset;
import java.util.Date;
import java.util.Objects;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author ziyuancheng
 * @since 2024-05-05
 */
@Service
public class SysVerificationCodeServiceImpl extends ServiceImpl<SysVerificationCodeMapper, SysVerificationCode> implements ISysVerificationCodeService {

    @Autowired
    private ISysUserService userService;

    @Autowired
    private SysVerificationCodeMapper verificationCodeMapper;
    @Resource
    private JavaMailSender javaMailSender;
    @Resource
    private AppConfig appConfig;
    @Resource
    private RedisComponent redisComponent;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sendEmailCode(String email, Integer type) {
        if (Objects.equals(type, Constants.ZERO)) {
            SysUser user = userService.getUserByEmail(email);
            if (ObjUtil.isNotEmpty(user)) {
                throw new RuntimeException("邮箱已经存在");
            }
        }
        //生成随机验证码五位
        String code = RandomUtil.randomString(Constants.RANK_5);

        //调用发送邮件的方法
        sendEmailCodeToEmail(email, code);

        //将之前的验证码置为无效
        verificationCodeMapper.disableEmailCode(email);

        //存入数据库
        SysVerificationCode sysVerificationCode = new SysVerificationCode(email, code, DateUtil.toLocalDateTime(new Date()), Constants.ZERO);
        verificationCodeMapper.insert(sysVerificationCode);
    }

    @Override
    public void checkCode(String email, String emailCode) {
        SysVerificationCode verificationCode = verificationCodeMapper.selectByEmailAndCode(email, emailCode);
        if (ObjectUtil.isEmpty(verificationCode)) {
            throw new BusinessException("邮箱验证码不正确");
        }
        if (Objects.equals(verificationCode.getStatus(), Constants.ONE)
                || System.currentTimeMillis() - verificationCode.getCreateTime().toEpochSecond(ZoneOffset.UTC) * 1000
                > Constants.RANK_15 * 1000 * 60) {
            throw new BusinessException("邮箱验证码已失效");
        }
        verificationCodeMapper.disableEmailCode(email);
    }


    private void sendEmailCodeToEmail(String toEmail, String code) {
        try {

            MimeMessage message = javaMailSender.createMimeMessage();

            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            //邮件发件人
            helper.setFrom(appConfig.getSendUserName());
            //邮件收件人 1或多个
            helper.setTo(toEmail);

            RegisterToSendEmails registerToSendEmails = redisComponent.getRegisterToSendEmails();

            //邮件主题
            helper.setSubject(registerToSendEmails.getRegisterEmailTitle());
            //邮件内容
            helper.setText(String.format(registerToSendEmails.getRegisterEmailContent(), code));
            //邮件发送时间
            helper.setSentDate(new Date());
            javaMailSender.send(message);
        } catch (Exception e) {
            log.error("邮件发送失败", e);
            throw new BusinessException("邮件发送失败");
        }
    }

}
